home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Macintosh Tracker 1.20 / source / Tracker Client Folder / Core 18⁄March⁄1994 / Utilities.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-24  |  9.2 KB  |  423 lines  |  [TEXT/KAHL]

  1. /* Utilities.c */
  2.  
  3. #include "Utilities.h"
  4. #include <SANE.h>
  5. #include "Memory.h"
  6.  
  7. /* Machine language note:  */
  8. /*  SUB.W  X,Y  means y=y-x */
  9. /* in other words, the result of an operation is stored always in the second */
  10. /* operand specified */
  11.  
  12.  
  13. /* MemCpy which does overlapping regions and calls BlockMove for large blocks */
  14. void            MemCpy(char* Target, char* Source, signed long NumBytes)
  15.     {
  16.         ERROR(NumBytes < 0,PRERR(ForceAbort,"MemCpy asked to copy negative number of bytes"));
  17.         if ((NumBytes > 128) && (NumBytes < 8388607L))
  18.             {
  19.                 /* for large blocks, we use the efficient operating system routine */
  20.                 BlockMove(Source,Target,NumBytes);
  21.             }
  22.          else
  23.             {
  24.                 if ((Target - Source >= 0) && (Target - Source < NumBytes))
  25.                     {
  26.                         /* if target starts within source, we have to copy in reverse. */
  27.                         Target += NumBytes;
  28.                         Source += NumBytes;
  29.                         while (NumBytes > 0)
  30.                             {
  31.                                 Target -= 1;
  32.                                 Source -= 1;
  33.                                 NumBytes -= 1;
  34.                                 Target[0] = Source[0];
  35.                             }
  36.                     }
  37.                  else
  38.                     {
  39.                         /* we can do normal copy */
  40.                         while (NumBytes > 0)
  41.                             {
  42.                                 NumBytes -= 1;
  43.                                 Target[0] = Source[0];
  44.                                 Target += 1;
  45.                                 Source += 1;
  46.                             }
  47.                     }
  48.             }
  49.     }
  50.  
  51.  
  52. /* Memory compare: returns True if both regions are identical */
  53. MyBoolean    MemEqu(char* First, char* Second, long NumBytes)
  54.     {
  55.         ERROR(NumBytes < 0,PRERR(ForceAbort,"MemEqu asked to test negative number of bytes"));
  56.         while (NumBytes > 0)
  57.             {
  58.                 if (First[0] != Second[0])
  59.                     {
  60.                         return False; /* not equal */
  61.                     }
  62.                 First += 1;
  63.                 Second += 1;
  64.                 NumBytes -= 1;
  65.             }
  66.         return True; /* no differences found, must be the same */
  67.     }
  68.  
  69.  
  70. /* the labs function */
  71. long        LAbs(long value)
  72.     {
  73.         if (value < 0)
  74.             {
  75.                 return -value;
  76.             }
  77.          else
  78.             {
  79.                 return value;
  80.             }
  81.     }
  82.  
  83.  
  84. /* number of chars in a C string */
  85. long        StrLen(register char* It)
  86.     {
  87.         long        Count;
  88.  
  89.         Count = 0;
  90.         while (It[Count] != 0)
  91.             {
  92.                 Count += 1;
  93.             }
  94.         return Count;
  95.     }
  96.  
  97.  
  98. /* get a C string from the resource file. */
  99. /* high word of StringID = ID of resource */
  100. /* low word of StringID = ID of string within that resource */
  101. Handle        GetCString(ulong StringID)
  102.     {
  103.         Handle    StrRes;
  104.         Ptr            StrList;
  105.         ulong        Scan;  /* scans the list by word (2 bytes) */
  106.         ushort    Count;
  107.         ushort    IDToFind;
  108.  
  109.         ERROR(ResLoad == 0,PRERR(ForceAbort,"Automatic resource loading is disabled."));
  110.         StrRes = GetResource('∫Cst',(StringID >> 16) & 0x0000ffff);
  111.         if (StrRes == NIL)
  112.             {
  113.                 PRERR(ForceAbort,"GetCString couldn't find string resource.");
  114.             }
  115.         ERROR(ResErr != noErr,PRERR(ForceAbort,"Resource Error occurred."));
  116.         HLock(StrRes);
  117.         StrList = *StrRes;  /* dereference */
  118.         IDToFind = 0x0000ffff & StringID;  /* isolate local ID */
  119.         Scan = 2;  /* start with the 2nd word */
  120.         Count = ((uchar*)StrList)[0] * 256 + ((uchar*)StrList)[1]; /* get number of items to do */
  121.         while (Count > 0)
  122.             {
  123.                 long        NumChars;
  124.  
  125.                 /* finding length of current string */
  126.                 NumChars = 0;
  127.                 while ( ((char*)StrList)[Scan + sizeof(short) + NumChars] != 0)
  128.                     {
  129.                         NumChars += 1;
  130.                     }
  131.                 if (((uchar*)StrList)[Scan] * 256 + ((uchar*)StrList)[Scan + 1] == IDToFind)
  132.                     {
  133.                         Handle        Temp;
  134.  
  135.                         /* we've found it! */
  136.                         /* Make a new handle to put it in */
  137.                         Temp = AllocHandle(NumChars);
  138.                         SetTag(Temp,"GetCString Result");
  139.                         HUnlock(StrRes);
  140.                         MemCpy(*Temp,&(((char*)StrList)[Scan+2]),NumChars);
  141.                         return Temp;
  142.                     }
  143.                 /* if length = 0, then skip 2+1 (+1) = 4 */
  144.                 /* if length = 1, then skip 2+2 = 4 */
  145.                 /* if length = 2, then skip 2+3 (+1) = 6... */
  146.                 Scan += (NumChars & 0xfffffffe /* trunc */) + 4;
  147.                 Count -= 1;  /* decrement the counter */
  148.             }
  149.         HUnlock(StrRes);
  150.         PRERR(ForceAbort,"GetCString couldn't find specified string in resource.");
  151.     }
  152.  
  153.  
  154. /* convert a hexadecimal character into a byte value */
  155. char        Hex2Byte(char Hex)
  156.     {
  157.         if ((Hex >= '0') && (Hex <= '9'))
  158.             {
  159.                 return Hex-'0';
  160.             }
  161.         if ((Hex >= 'a') && (Hex <= 'f'))
  162.             {
  163.                 return Hex-'a'+10;
  164.             }
  165.         if ((Hex >= 'A') && (Hex <= 'F'))
  166.             {
  167.                 return Hex-'A'+10;
  168.             }
  169.         return -1;  /* conversion error */
  170.     }
  171.  
  172.  
  173. /* convert a byte to a hexadecimal character */
  174. char        Byte2Hex(char Value)
  175.     {
  176.         static char    Table[16] = "0123456789abcdef";
  177.  
  178.         return Table[Value];
  179.     }
  180.  
  181.  
  182. /* convert a real number to a string handle (with no length delimitors) */
  183. Handle    Real2String(long double Value, char Mode, short Digits)
  184.     {
  185.         PString        TempString;
  186.         extended    TempReal;
  187.         decform        TempDecForm;
  188.         Handle        RetStr;
  189.  
  190.         TempDecForm.style = Mode;
  191.         TempDecForm.digits = Digits;
  192.         #if !__option(mc68881) && __option(native_fp)
  193.             TempReal = Value;
  194.         #else
  195.             x96tox80(&Value,&TempReal); /* coerce the long double to extended format */
  196.         #endif
  197.         num2str(&TempDecForm,TempReal,TempString);
  198.         RetStr = AllocHandle(TempString[0]); /* return length of string */
  199.         SetTag(RetStr,"Real2String Return");
  200.         MemCpy(*RetStr,(char*)&(TempString[1]),TempString[0]);
  201.         return RetStr;
  202.     }
  203.  
  204.  
  205. /* convert a string to a real number */
  206. long double        String2Real(Handle StringHandle)
  207.     {
  208.         PString        TempStr;
  209.         decimal        TempDecimal;
  210.         Boolean        TempBoolean; /* has to be operating system's Boolean typedef */
  211.         short            TempShort;
  212.         long double    TempReal;
  213.         extended    TempExtended;
  214.  
  215.         Handle2PString(StringHandle,TempStr);
  216.         str2dec(TempStr,&TempShort,&TempDecimal,&TempBoolean);
  217.         TempExtended = dec2num(&TempDecimal);
  218.         #if !__option(mc68881) && __option(native_fp)
  219.             return TempExtended;
  220.         #else
  221.             x80tox96(&TempExtended,&TempReal); /* coerce to long double format */
  222.             return TempReal;
  223.         #endif
  224.     }
  225.  
  226.  
  227. Handle    HDuplicate(Handle Original)
  228.     {
  229.         Handle        Temp;
  230.  
  231.         if (Original == NIL)
  232.             {
  233.                 Temp = AllocHandle(0); /* return an empty handle */
  234.                 SetTag(Temp,"HDuplicate Result");
  235.                 return Temp;
  236.             }
  237.         CheckHandleExistence(Original);
  238.         Temp = AllocHandle(HandleSize(Original));
  239.         SetTag(Temp,"HDuplicate Result");
  240.         MemCpy(*Temp,*Original,HandleSize(Original));
  241.         return Temp;
  242.     }
  243.  
  244.  
  245. void        Handle2PString(Handle Source, PString PlaceToPut)
  246.     {
  247.         long        Length;
  248.         short        Scan;
  249.  
  250.         CheckHandleExistence(Source);
  251.         Length = HandleSize(Source);
  252.         if (Length > (sizeof(PString)-1))
  253.             {
  254.                 Length = sizeof(PString) - 1;
  255.             }
  256.         PlaceToPut[0] = Length;
  257.         for (Scan = 0; Scan < Length; Scan += 1)
  258.             {
  259.                 PlaceToPut[Scan+1] = ((char*)*Source)[Scan];
  260.             }
  261.     }
  262.  
  263.  
  264. Handle    PString2Handle(PString String)
  265.     {
  266.         Handle    Temp;
  267.  
  268.         Temp = AllocHandle((uchar)(String[0]));
  269.         SetTag(Temp,"PString2Handle Return");
  270.         MemCpy(*Temp,(char*)&(String[1]),String[0]);
  271.         return Temp;
  272.     }
  273.  
  274.  
  275. Handle    HStrCat(Handle First, Handle Second)
  276.     {
  277.         Handle    Temp;
  278.  
  279.         CheckHandleExistence(First);
  280.         CheckHandleExistence(Second);
  281.         Temp = AllocHandle(HandleSize(First) + HandleSize(Second));
  282.         SetTag(Temp,"HStrCat Return");
  283.         MemCpy(*Temp,*First,HandleSize(First));
  284.         MemCpy(&((*Temp)[HandleSize(First)]),*Second,HandleSize(Second));
  285.         return Temp;
  286.     }
  287.  
  288.  
  289. Handle    HandleOf(char* Data, long NumBytes)
  290.     {
  291.         Handle    Temp;
  292.  
  293.         Temp = AllocHandle(NumBytes);
  294.         SetTag(Temp,"HandleOf Return");
  295.         MemCpy(*Temp,Data,NumBytes);
  296.         return Temp;
  297.     }
  298.  
  299.  
  300. /* convert a long integer to a string handle */
  301. Handle    Int2String(long TheInt)
  302.     {
  303.         char        Buffer[20];
  304.         short        BufPtr;
  305.         char        Buf[20];
  306.         short        BPtr;
  307.         short        Scan;
  308.  
  309.         BufPtr = 1;
  310.         if (TheInt == -2147483648)
  311.             {
  312.                 return PString2Handle("\p-2147483648");
  313.             }
  314.          else
  315.             {
  316.                 if (TheInt < 0)
  317.                     {
  318.                         Buffer[BufPtr++] = '-';
  319.                         TheInt = -TheInt;
  320.                     }
  321.                 BPtr = 16;
  322.                 Buf[--BPtr] = 0;
  323.                 do
  324.                     {
  325.                         Buf[--BPtr] = (TheInt % 10) + '0';
  326.                         TheInt = TheInt / 10;
  327.                     } while (TheInt != 0);
  328.                 for (Scan = BPtr; Scan < 16; Scan += 1)
  329.                     {
  330.                         Buffer[BufPtr++] = Buf[Scan];
  331.                     }
  332.             }
  333.         Buffer[0] = BufPtr - 1;
  334.         return PString2Handle((uchar*)Buffer);
  335.     }
  336.  
  337.  
  338. /* convert a string to an integer */
  339. long        String2Int(Handle StringHand)
  340.     {
  341.         MyBoolean        Sign = False;
  342.         long                Accr;
  343.         long                Scan;
  344.  
  345.         Scan = 0;
  346.         Accr = 0;
  347.         while (((*StringHand)[Scan] == 32) && (Scan < HandleSize(StringHand)))
  348.             {
  349.                 Scan += 1;
  350.             }
  351.         while (Scan < HandleSize(StringHand))
  352.             {
  353.                 if ((*StringHand)[Scan] == '-')
  354.                     {
  355.                         Sign = !Sign;
  356.                     }
  357.                 if (((*StringHand)[Scan] >= '0') && ((*StringHand)[Scan] <= '9'))
  358.                     {
  359.                         Accr = (10 * Accr) + ((*StringHand)[Scan] - '0');
  360.                     }
  361.                 Scan += 1;
  362.             }
  363.         return Accr;
  364.     }
  365.  
  366.  
  367. /* compare 2 strings.  -1 = first is ahead of second, 0 = identical, 1 = second */
  368. /* is ahead of first */
  369. short        HStrCmp(Handle First, Handle Second)
  370.     {
  371.         register char*    FScan;
  372.         register char*    SScan;
  373.         register long        Count;
  374.         long                        SecondSize;
  375.         MyBoolean                Flag;
  376.         MyBoolean                SecondLongerThanFirst;
  377.  
  378.         CheckHandleExistence(First);
  379.         CheckHandleExistence(Second);
  380.         Count = HandleSize(First);
  381.         SecondSize = HandleSize(Second);
  382.         Flag = (SecondSize == Count);
  383.         SecondLongerThanFirst = (SecondSize > Count);
  384.         if (SecondSize < Count)
  385.             {
  386.                 Count = SecondSize;
  387.             }
  388.         FScan = *First;
  389.         SScan = *Second;
  390.         while (Count > 0)
  391.             {
  392.                 register char        Temp1;
  393.                 register char        Temp2;
  394.  
  395.                 Temp1 = *(FScan++);
  396.                 Temp2 = *(SScan++);
  397.                 if (Temp1 < Temp2)
  398.                     {
  399.                         return -1; /* String1 < String2 */
  400.                     }
  401.                 if (Temp1 > Temp2)
  402.                     {
  403.                         return 1; /* String1 > String2 */
  404.                     }
  405.                 Count -= 1;
  406.             }
  407.         if (Flag)
  408.             {
  409.                 return 0; /* if same length, then identical */
  410.             }
  411.          else
  412.             {
  413.                 if (SecondLongerThanFirst)
  414.                     {
  415.                         return -1; /* smaller string extended with nulls < larger */
  416.                     }
  417.                  else
  418.                     {
  419.                         return 1;
  420.                     }
  421.             }
  422.     }
  423.